import install, { Vue } from './install';
import {createMatcher} from './create-matcher'
import HashHistory from './history/hash';
import HTML5History from './history/h5';
class VueRouter {
  constructor(options = {}) {
    const routes = options.routes;
    this.mode = options.mode || 'hash';

    // 给我个路径 我就返回给你对应的记录，处理树形结构，将routes扁平化
    // 返回两个方法：addRoutes 动态添加路由 ， match匹配方法
    this.matcher = createMatcher(options.routes || []);

    // 根据模式需要初始化不同的路由系统  hash/history 底层实现不一样 ，但是使用的方式是一样的
    // hash => hash.js  => push
    // history => history.js => push
    // base

    // 每次跳转 我需要获取当前的路径 this.$router.pathname
    switch (this.mode) {
      case 'hash': // location.hash  => push
        this.history = new HashHistory(this)
        break
      case 'history': // pushState => push
        this.history = new HTML5History(this);
        break

    }
    this.beforeHooks = []
  }
  match(location) { //只要路径一切换，就调用匹配器进行匹配，将匹配的结果返给我
    return this.matcher.match(location);
  }
  push(location) {
    // 跳转页面
    this.history.transitionTo(location, () => {
      // pushState
      this.history.pushState(location);
    })
  }
  //初始化方法
  init(app) {
    const history = this.history; // 当前管理路由的
    // hash  -》 hashchange  但是浏览器支持popstate 就优先采用popstate
    // history -> popState  性能高于hashchange 但是有兼容性问题

    // 页面初始化完毕后 需要先进行一次跳转

    // 跳转到某个路径
    const setupHashListener = () => { //跳转成功后的回调
      history.setupListener();// 监听路由变化
    }
    history.transitionTo( //跳转的方法
      history.getCurrentLocation(), // 获取当前路径方法
      setupHashListener
    );
    //setupListener  监听路由变化
    //transitionTo  跳转的方法
    //getCurrentLocation  获取当前路径方法
    history.listen((route) => {
      // 监听 监听如果current变化了 就重新的给 _route赋值
      app._route = route;
    })
  }
  beforeEach(fn) {
    this.beforeHooks.push(fn);//页面切换之前，会先执行这些方法
  }
}
VueRouter.install = install;


export default VueRouter


// 路由的钩子执行的思路 和 koa -> express 中间件的原理是一样的  就是把u偶有的钩子组成一个数组依次执行